<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use App\Services\Admin\LogsService;

class LogMiddleware
{
    protected $logService;
    private $adminId = 0;
    private $adminName = '未知用户';

    public function __construct(LogsService $logService)
    {
        $this->logService = $logService;
    }

    /**
     * 获取模块名称
     * @param string $module
     * @return string
     */
    protected function getModuleName(string $module): string
    {
        $moduleNames = config('modules', []);
        return $moduleNames[$module] ?? $module;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        if (Auth::guard('admin')->check()) {
            $admin = Auth::guard('admin')->user();
            $this->adminId = $admin->id ?? 0;
            $this->adminName = $admin->real_name ? $admin->real_name : ($admin->username ? $admin->username : '未知用户');
        }

        $startTime = microtime(true);

        $response = $next($request);

        $endTime = microtime(true);
        $responseTime = round(($endTime - $startTime) * 1000); // 转换为毫秒

        // 从完整的控制器路径中提取控制器名称
        $route = $request->route();
        if (empty($route[1]['uses'])) {
            return $response;
        }

        $uses = $route[1]['uses'];
        list($controller, $action) = explode('@', $uses);
        $controllerName = class_basename($controller);
        $controllerName = lcfirst(str_replace('Controller', '', $controllerName));
        $key = strtolower($controllerName . '.' . $action);

        $routes = config('admin-routes');
        if (!isset($routes[$key])) {
            return $response;
        }

        $route = $routes[$key];
        $this->addLogRecord($request, $response, $responseTime, $key, $route);

        return $response;
    }

    /**
     * 记录操作日志
     * @param Request $request
     * @param mixed $response
     * @param int $responseTime
     * @param string $key
     * @param array $route
     */
    private function addLogRecord(Request $request, $response, int $responseTime, string $key, array $route): void
    {
        try {
            // 登录操作后获取管理员
            if (!$this->adminId && Auth::guard('admin')->check()) {
                $admin = Auth::guard('admin')->user();
                $this->adminId = $admin->id ?? 0;
                $this->adminName = $admin->real_name ? $admin->real_name : ($admin->username ? $admin->username : '未知用户');
            }
            list($module, $action) = explode('.', $key);
            $method = $route['method'];
            $eventName = $route['desc'];
            $content = $this->generateContent($this->adminName, $module, $action, $method, $route['desc']);
            $reportKeys = ['operationlog.accesswrite'];
            if (in_array($key, $reportKeys)) {
                $eventName = $request->input('event_name', $eventName);
                $content = $request->input('content', $this->generateContent($this->adminName, $module, $action, $method, $eventName));
            }
            $data = [
                'event_name' => $eventName,
                'content' => $content,
                'url' => $request->fullUrl(),
                'query' => json_encode($request->query(), JSON_UNESCAPED_UNICODE),
                'params' => json_encode($request->all(), JSON_UNESCAPED_UNICODE),
                'response' => json_encode($response, JSON_UNESCAPED_UNICODE),
                'ip' => $request->ip(),
                'user_agent' => $request->userAgent(),
                'method' => $method,
                'module' => $module,
                'action' => $action,
                'status_code' => $response->getStatusCode(),
                'response_time' => $responseTime,
            ];
            $this->logService->create($data, $this->adminId);
        } catch (\Exception $e) {
            // 记录日志失败时不影响正常请求
            Log::error('日志中间件记录失败: ' . $e->getMessage());
        }
    }

    /**
     * 生成操作内容
     * @param string $adminName
     * @param string $module
     * @param string $action
     * @param string $method
     * @param string $desc
     * @return string
     */
    protected function generateContent(string $adminName, string $module, string $action, string $method, string $desc): string
    {
        $moduleName = $this->getModuleName($module);
        $eventName = $method === 'get' ? '访问了' : '操作了';
        if ($desc) {
            $eventName .= ' ' . $desc;
        } else {
            $eventName .= ' ' . $action;
        }
        return "管理员 {$adminName} 在 {$moduleName} 模块 {$eventName}";
    }
}
